package hms.ReservationsModule;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Calendar;

import hms.database.DBJFrame;
import hms.date.DateHandler;
import hms.generic.AbstractGlobalView;
import hms.permissions.Permission;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.MaskFormatter;

public class GuestInformationView extends AbstractGlobalView implements
		ListSelectionListener {

	// /////////////////////////
	// // Global GUI Fields ////
	// /////////////////////////

	private JTextField firstName;
	private JTextField lastName;
	private JTextField address;
	private JTextField city;
	private JComboBox state;
	private JTextField country;
	private JComboBox gender;
	private JFormattedTextField homePhone;
	private JFormattedTextField mobilePhone;
	private JFormattedTextField workPhone;
	private JTextArea comments;
	private JComboBox birthMonth;
	private JComboBox birthDay;
	private JFormattedTextField birthYear;
	private BirthHandler birthdayHandler;
	private JCheckBox vipCheckBox;

	private DBJFrame<GuestTable, Guest> guestJFrame;
	private JButton addGuest;
	private JButton removeGuest;
	private JButton saveInformation;
	private Guest currentGuest;
	
	private boolean loading;

	private static final String[] states = { "AL", "AK", "AS", "AZ", "AR",
			"CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID",
			"IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI",
			"MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC",
			"ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD",
			"TN", "TX", "UT", "VT", "VI", "VA", "WA", "WV", "WI", "WY" };

	private static final String[] genders = { "M", "F" };

	final String[] months = { "Janurary", "February", "March", "April", "May",
			"June", "July", "August", "September", "October", "November",
			"December" };

	/////////////////////
	//// Constructor ////
	/////////////////////

	public GuestInformationView() {

		// Data model
		GuestTable guests = new GuestTable();
		currentGuest = null;
		loading = false;

		/////////////////////////////
		//// Create GUI elements ////
		/////////////////////////////

		JPanel mainPanel = new JPanel();
		JPanel selectGuest = new JPanel();
		selectGuest.setBorder(BorderFactory.createTitledBorder("Select Guest"));
		JPanel information = new JPanel();
		information.setBorder(BorderFactory.createTitledBorder("Information"));
		guestJFrame = new DBJFrame<GuestTable, Guest>(guests);
		addGuest = new JButton("Add Guest");
		removeGuest = new JButton("Remove Guest");
		JLabel firstNameLabel = new JLabel("First Name");
		firstName = new JTextField();
		JLabel lastNameLabel = new JLabel("Last Name");
		lastName = new JTextField();
		JLabel addressLabel = new JLabel("Address");
		address = new JTextField();
		JLabel cityLabel = new JLabel("City");
		city = new JTextField();
		JLabel stateLabel = new JLabel("State");
		state = new JComboBox(states);
		JLabel countryLabel = new JLabel("Country");
		country = new JTextField();
		JLabel genderLabel = new JLabel("Gender");
		gender = new JComboBox(genders);
		JLabel homePhoneLabel = new JLabel("Home Phone");
		MaskFormatter phoneFormat1=null;
		MaskFormatter phoneFormat2=null;
		MaskFormatter phoneFormat3=null;
		try {
			phoneFormat1 = new MaskFormatter("(###) ###-####");
			phoneFormat2 = new MaskFormatter("(###) ###-####");
			phoneFormat3 = new MaskFormatter("(###) ###-####");
			
		} catch (ParseException e) {
			
			e.printStackTrace();
		}
		homePhone = new JFormattedTextField(phoneFormat1);
		JLabel mobilePhoneLabel = new JLabel("Mobile Phone");
		mobilePhone = new JFormattedTextField(phoneFormat2);
		JLabel workPhoneLabel = new JLabel("Work Phone");
		workPhone = new JFormattedTextField(phoneFormat3);
		comments = new JTextArea();
		JLabel birthDateLabel = new JLabel("Birth Date");
		birthMonth = new JComboBox(months);
		birthDay = new JComboBox();
		birthYear = new JFormattedTextField(new DecimalFormat("####"));
		JLabel vipLabel = new JLabel("VIP");
		vipCheckBox = new JCheckBox();
		JLabel commentsLabel = new JLabel("Comments");
		comments = new JTextArea();
		if(checkPermission(Permission.CHECK_IN_OUT)){
			saveInformation = new JButton("Save information");
		} else {
			saveInformation = new JButton("Can't Save - need permission");
		}

		//////////////////////////////
		//// Listener assignments ////
		//////////////////////////////

		guestJFrame.getJList().addListSelectionListener(this);
		birthdayHandler = new BirthHandler(birthMonth, birthDay, birthYear);
		addGuest.addActionListener(new AddListener());
		removeGuest.addActionListener(new RemoveListener());
		if(checkPermission(Permission.CHECK_IN_OUT)) {
			saveInformation.addActionListener(new CommitListener());
		}
		firstName.getDocument().addDocumentListener(new ChangeHandler());
		lastName.getDocument().addDocumentListener(new ChangeHandler());
		gender.addActionListener(new ChangeHandler());
		address.getDocument().addDocumentListener(new ChangeHandler());
		city.getDocument().addDocumentListener(new ChangeHandler());
		state.addActionListener(new ChangeHandler());
		country.getDocument().addDocumentListener(new ChangeHandler());
		homePhone.getDocument().addDocumentListener(new ChangeHandler());
		mobilePhone.getDocument().addDocumentListener(new ChangeHandler());
		workPhone.getDocument().addDocumentListener(new ChangeHandler());
		birthMonth.addActionListener(new ChangeHandler());
		birthDay.addActionListener(new ChangeHandler());
		birthYear.getDocument().addDocumentListener(new ChangeHandler());
		vipCheckBox.addActionListener(new ChangeHandler());
		comments.getDocument().addDocumentListener(new ChangeHandler());
		

		/////////////////////////
		//// Layout elements ////
		/////////////////////////

		GridBagConstraints c;

		// Select guest panel
		// init
		c = new GridBagConstraints();
		selectGuest.setLayout(new GridBagLayout());
		c.insets = new Insets(10, 10, 10, 10);
		c.fill = GridBagConstraints.BOTH;
		c.anchor = GridBagConstraints.CENTER;

		// Pane
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2;
		c.weighty = 1;
		selectGuest.add(guestJFrame.getContentPane(), c);

		// Buttons
		c.gridy = 1;
		c.gridwidth = 1;
		c.weighty = 0;
		selectGuest.add(addGuest, c);
		c.gridx = 1;
		//selectGuest.add(removeGuest, c);

		// Information Panel
		c = new GridBagConstraints();
		information.setLayout(new GridBagLayout());
		c.weightx = .2;

		// Labels
		c.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING;
		c.weighty = .5;

		c.gridx = 0;
		c.gridy = 0;
		information.add(firstNameLabel, c);

		c.gridx = 1;
		c.gridy = 0;
		information.add(lastNameLabel, c);

		c.gridx = 3;
		c.gridy = 0;
		information.add(genderLabel, c);

		c.gridx = 0;
		c.gridy = 2;
		information.add(addressLabel, c);

		c.gridx = 0;
		c.gridy = 4;
		information.add(cityLabel, c);

		c.gridx = 1;
		c.gridy = 4;
		information.add(stateLabel, c);

		c.gridx = 3;
		c.gridy = 4;
		information.add(countryLabel, c);

		c.gridx = 0;
		c.gridy = 6;
		information.add(homePhoneLabel, c);

		c.gridx = 1;
		c.gridy = 6;
		information.add(mobilePhoneLabel, c);

		c.gridx = 3;
		c.gridy = 6;
		information.add(workPhoneLabel, c);

		c.gridx = 0;
		c.gridy = 8;
		information.add(birthDateLabel, c);

		// Elements
		c.weighty = .15;
		c.anchor = GridBagConstraints.CENTER;
		c.insets = new Insets(10, 10, 10, 10);
		c.fill = GridBagConstraints.HORIZONTAL;

		c.gridx = 0;
		c.gridy = 1;
		c.gridwidth = 1;
		information.add(firstName, c);

		c.gridx = 1;
		c.gridy = 1;
		c.gridwidth = 2;
		information.add(lastName, c);

		c.gridx = 3;
		c.gridy = 1;
		c.gridwidth = 1;
		information.add(gender, c);

		c.gridx = 0;
		c.gridy = 3;
		c.gridwidth = 5;
		information.add(address, c);

		c.gridx = 0;
		c.gridy = 5;
		c.gridwidth = 1;
		information.add(city, c);

		c.gridx = 1;
		c.gridy = 5;
		c.gridwidth = 1;
		information.add(state, c);

		c.gridx = 3;
		c.gridy = 5;
		c.gridwidth = 21;
		information.add(country, c);

		c.gridx = 0;
		c.gridy = 7;
		c.gridwidth = 1;
		information.add(homePhone, c);

		c.gridx = 1;
		c.gridy = 7;
		c.gridwidth = 2;
		information.add(mobilePhone, c);

		c.gridx = 3;
		c.gridy = 7;
		c.gridwidth = 2;
		information.add(workPhone, c);

		c.gridx = 0;
		c.gridy = 9;
		c.gridwidth = 1;
		information.add(birthMonth, c);

		c.gridx = 1;
		c.gridy = 9;
		c.gridwidth = 1;
		information.add(birthDay, c);

		c.gridx = 2;
		c.gridy = 9;
		c.gridwidth = 1;
		information.add(birthYear, c);

		c.gridx = 3;
		c.gridy = 9;
		c.gridwidth = 1;
		c.anchor = GridBagConstraints.ABOVE_BASELINE_TRAILING;
		information.add(vipLabel, c);
		c.anchor = GridBagConstraints.ABOVE_BASELINE_LEADING;

		c.gridx = 4;
		c.gridy = 9;
		c.gridwidth = 1;
		information.add(vipCheckBox, c);

		c.gridx = 0;
		c.gridy = 10;
		c.gridwidth = 1;
		information.add(commentsLabel, c);

		c.gridx = 0;
		c.gridy = 11;
		c.gridwidth = 3;
		information.add(comments, c);

		c.gridx = 3;
		c.gridy = 10;
		c.gridwidth = 2;
		c.gridheight = 2;
		c.fill = GridBagConstraints.BOTH;
		information.add(saveInformation, c);

		// Main Panel
		// init
		c = new GridBagConstraints();
		mainPanel.setLayout(new GridBagLayout());
		c.insets = new Insets(10, 10, 10, 10);
		c.anchor = GridBagConstraints.CENTER;
		c.fill = GridBagConstraints.BOTH;

		c.gridx = 0;
		c.gridy = 0;
		c.weightx = 0;
		mainPanel.add(selectGuest, c);
		c.gridx = 1;
		c.weightx = 1;
		mainPanel.add(information, c);

		if(!checkPermission(Permission.CHECK_IN_OUT)) {
			addGuest.setVisible(false);
			removeGuest.setVisible(false);
		}
		
		// /////////////////////
		// // Display Panel ////
		// /////////////////////

		super.update(mainPanel);
		super.display();
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {

	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		if (currentGuest == null
				|| !currentGuest.equals(guestJFrame.getSelectedRowObject())) {
			saveData();
			// Load code
			loading = true;
			currentGuest = guestJFrame.getSelectedRowObject();
			if (currentGuest != null) {
				firstName.setText(currentGuest.getFirstName());
				lastName.setText(currentGuest.getLastName());
				gender.setSelectedItem(currentGuest.getGender());
				address.setText(currentGuest.getAddress());
				city.setText(currentGuest.getCity());
				state.setSelectedItem(currentGuest.getState());
				country.setText(currentGuest.getCountry());
				homePhone.setText(currentGuest.getHomephone());
				mobilePhone.setText(currentGuest.getMobilephone());
				workPhone.setText(currentGuest.getWorkphone());
				birthdayHandler.setDate(currentGuest.getDate_of_birth());
				vipCheckBox.setSelected(currentGuest.isVip_status());
				comments.setText(currentGuest.getComments());
			} else {
				firstName.setText(null);
				lastName.setText(null);
				gender.setSelectedIndex(0);
				address.setText(null);
				city.setText(null);
				state.setSelectedIndex(0);
				country.setText(null);
				homePhone.setText(null);
				mobilePhone.setText(null);
				workPhone.setText(null);
				birthdayHandler.reset();
				vipCheckBox.setSelected(false);
				comments.setText(null);
			}
			loading = false;
		}
	}

	public void saveData() {
		if (currentGuest != null) {
			// Save code
			currentGuest.setFirstName(firstName.getText());
			currentGuest.setLastName(lastName.getText());
			currentGuest.setGender(gender.getSelectedItem().toString());
			currentGuest.setAddress(address.getText());
			currentGuest.setCity(city.getText());
			currentGuest.setState(state.getSelectedItem().toString());
			currentGuest.setCountry(country.getText());
			currentGuest.setHomephone(homePhone.getText().replaceAll("[^0-9]",
					""));
			currentGuest.setWorkphone(workPhone.getText().replaceAll("[^0-9]",
					""));
			currentGuest.setMobilephone(mobilePhone.getText().replaceAll(
					"[^0-9]", ""));
			Calendar c = birthdayHandler.getDate();
			c.set(Calendar.MONTH, c.get(Calendar.MONTH) - 1);
			currentGuest.setDate_of_birth(c);
			currentGuest.setVip_status(vipCheckBox.isSelected());
			currentGuest.setComments(comments.getText());
		}
	}
	
	public class BirthHandler extends DateHandler {

		public BirthHandler(JComboBox month, JComboBox day,
				JFormattedTextField year) {
			super(month, day, year);
		}

		@Override
		public void writeOut(int year, int month, int day) {

		}

	}
	
	@Override
	public void informationWillBeLost() {
		if(!loading) {
			super.informationWillBeLost();
		}
	}
	
	class ChangeHandler implements ActionListener, DocumentListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			informationWillBeLost();
		}
		
        //Required by DocumentListener.
        public void insertUpdate(DocumentEvent e) {

			informationWillBeLost();
        }

        //Required by DocumentListener.
        public void removeUpdate(DocumentEvent e) {
        	// TODO [ben] handle blank fields
			informationWillBeLost();
        }

        //Required by DocumentListener.
        public void changedUpdate(DocumentEvent e) {

			informationWillBeLost();
        }
		
	}
	
	class AddListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			guestJFrame.addToList(new Guest());
			informationWillBeLost();
		}
	}
	
	class RemoveListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			guestJFrame.removeSelected();
			informationWillBeLost();
		}
	}
	
	class CommitListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			saveData();
			guestJFrame.commitToDatabase();
			informationHasBeenSaved();
		}
	}

}
